package org.shapeoforion.ui;

import org.apache.commons.logging.Log;
import org.shapeoforion.log.MyLogger;
import org.shapeoforion.utils.timer.Sleeper;
import org.shapeoforion.utils.timer.SleeperFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

/**
 * Contains the abstract game.
 * <p/>
 * The abstract game contains functionality for entering fullscreen, enabling animation (double/tripple buffers) etc.
 *
 * @author jps
 * @version 0.1s
 */
public abstract class AbstractAnimationFrame extends JFrame {

    private static final Log LOG = MyLogger.getInstance(AbstractAnimationFrame.class);

    protected void enterFullscreen() {

        LOG.info("entering fullscreen exclusive");
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice device = ge.getDefaultScreenDevice();

        if (device.isFullScreenSupported()) {

            LOG.debug("FSE is supported on this device");

            setUndecorated(true); // turn off borders and windows and stuff
            setIgnoreRepaint(true); // ignore swing paints events
            setResizable(false); // no reason to resize in full-screen

            // here we go...
            LOG.debug("FSE now!");
            //device.setFullScreenWindow(this);

        } else {
            LOG.warn("FSE is not supported on this device");
        }
    }

    protected void doGameLoop() {

        LOG.debug("entering game loop");

        BufferStrategy strategy = getBufferStrategy();
        while (isGameRunning()) {

            render((Graphics2D) strategy.getDrawGraphics());
            sleeper.sleep(20);
            frames++;
        }
    }

    /**
     * Start the game.
     * <p/>
     * basically, this only sets in action the render loop.
     */
    public void start() {

        LOG.info("starting");

        // create two buffers (for double buffering)
        createBufferStrategy(BUFFERS);

        doGameLoop();
    }

    /**
     * Perform the rendering of a frame
     *
     * @param g the Graphics2D object to perform the rendering in
     */
    protected abstract void render(Graphics2D g);

    /**
     * Test if the game is running - if so, the gameloop should continue.
     *
     * @return true if the game is running, else false (duh)
     */
    protected abstract boolean isGameRunning();

    private Sleeper sleeper = SleeperFactory.getSleeper();
    private int frames = 0;

    private static final int BUFFERS = 2;
}
